using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using TTDotNet.Util;

namespace TTDotNet.Engine.ThreeDEngine
{
    public class AJObject
    {
        protected Vector3 myPosition = new Vector3(0, 0, 0);   // We will use these for
        protected Vector3 myRotation = new Vector3(0, 0, 0);   // building our transformation
        protected Vector3 myScaling = new Vector3(1, 1, 1);   // matrices in the camera later
        public Vector3 mySize = new Vector3(1, 1, 1);
        public float radius;
        protected bool IsVisible = true;
        private ObjectType objectType;
        
        public virtual void ReloadResources() { } // This will be used for device resets
        public virtual void Render(AJCamera camera) { }          // Basic render call for every object

        public virtual ObjectInstance Pick(Vector3 rayStart, Vector3 rayDirection, AJCamera camera, out IntersectInformation intInf) 
        { 
            intInf = new IntersectInformation(); 
            return new ObjectInstance(null, Guid.Empty); 
        }

        public virtual void setTexture(Device Device, string path){ }

        public AJObject(ObjectType type)
        {
            objectType = type;
        }

        public void SetPosition(Vector3 newPos)
        {
            this.myPosition = newPos;
            myPosition.Y += mySize.Y / 2;
        }

        public void SetRotation(Vector3 newRot)
        {
            this.myRotation.X = Geometry.DegreeToRadian(newRot.X);
            this.myRotation.Y = Geometry.DegreeToRadian(newRot.Y);
            this.myRotation.Z = Geometry.DegreeToRadian(newRot.Z);
        }

        public void SetRotation(Axis axis, float rotateTo)
        {
            if (axis == Axis.X) myRotation.X = Geometry.DegreeToRadian(rotateTo);
            if (axis == Axis.Y) myRotation.Y = Geometry.DegreeToRadian(rotateTo);
            if (axis == Axis.Z) myRotation.Z = Geometry.DegreeToRadian(rotateTo);
        }

        public Vector3 Rotation
        {
            get { return new Vector3(myRotation.X, myRotation.Y, myRotation.Z); }
        }

        public virtual void SetScaling(Vector3 newScale)
        {
            this.myScaling = newScale;
        }

        public virtual void ScaleBy(Vector3 scaleFactor)
        {

            //myPosition.Y -= (mySize.Y - (mySize.Y * scaleFactor.Y)) / 2;

            myScaling.X *= scaleFactor.X;
            myScaling.Y *= scaleFactor.Y;
            myScaling.Z *= scaleFactor.Z;
        }

        public Vector3 GetPosition()
        {
            return myPosition;
        }

        public ObjectType ObjectType
        {
            get { return objectType; }
        }

        protected virtual void ComputeRadius() { }

    }

    public struct ObjectInstance
    {
        private AJObject obj;
        private Guid guid;

        public ObjectInstance(AJObject obj, Guid guid)
        {
            this.obj = obj;
            this.guid = guid;
        }

        public AJObject Object
        {
            get { return obj; }
        }

        public Guid GUID
        {
            get { return guid; }
            set { guid = value; }
        }

        public bool IsEmpty
        {
            get { return guid == Guid.Empty; }
        }
    }
}
